import random
from time import sleep
from selenium.webdriver.support import expected_conditions as EC

from selenium.webdriver.support.wait import WebDriverWait


def random_str(n):
    str = ""
    for i in random.sample('0123456789', n):
        str = str + i
    return str


class Base:
    err_count = 0
    err_max = 10
    black_list = []
    params = {'memberAdd_acctid': random_str(8), 'memberAdd_phone': "156" + random_str(8)}

    def __init__(self, driver, data):
        self.driver = driver
        self.driver.implicitly_wait(5)
        self.base_url = data['data']['base_url']

    def find(self, by, locator=None):
        try:
            element = self.driver.find_elements(*by) if isinstance(by, tuple) else self.driver.find_element(by, locator)
            return element
        except Exception as e:
            self.err_count += 1
            if self.err_count >= self.err_max:
                raise Exception('超过最大错误次数')
            for black in self.black_list:
                element = self.driver.find_elements(*black)
                if len(element) > 0:
                    element[0].click()
                    return self.find(by, locator)
            raise Exception('未知弹框定位')

    def send(self, value, by, locator=None):
        try:
            self.find(by, locator).send_keys(value)
        except Exception as e:
            self.err_count += 1
            if self.err_count >= self.err_max:
                raise Exception('超过最大错误次数')
            for black in self.black_list:
                element = self.driver.find_elements(*black)
                if len(element) > 0:
                    element[0].click()
                    return self.send(value, by, locator)
            raise Exception('未知弹框定位')

    def steps(self, step):
        if 'action' in step.keys():
            if "get_url" == step["action"]:
                self.get_url(step['url'])
                return
            if "wait" in step.keys():
                sleep(step['wait'])
            element = self.find(step['by'], step['locator'])
            if "until_wait" in step.keys():
                WebDriverWait(self.driver, step['until_wait']).until(
                    EC.presence_of_element_located((step['by'], step['locator'])))
            if 'click' == step['action']:
                element.click()
            if 'send' == step['action']:
                content: str = step['value']
                # for param in self.params:
                if content in self.params.keys():
                    content = content.replace(f'{content}', self.params[content])
                self.send(content, step['by'], step['locator'])
            if 'slide' == step["action"]:
                self.Slide_mouse01(element)
            if 'assert' == step["action"]:
                target = element.text
                assert target == step["expect"]
        else:
            raise Exception('yaml文件数据异常')

    def save_shot(self, path):
        """
        保存截图
        :param path:保存地址及名称
        :return:
        """
        self.driver.save_screenshot(path)

    def get_url(self, url):
        """
        跳转到指定页面
        :return:
        """
        self.driver.get(self.base_url + url)

    def Slide_mouse01(self, element):
        """
        鼠标滑动到目标元素element
        :return:
        """
        self.driver.execute_script("arguments[0].scrollIntoView();", element)

    def Slide_mouse02(self):
        """
        鼠标滑动到顶部
        :return:
        """
        js = "window.scroll(0,0)"
        self.driver.execute_script(js)

    def Slide_mouse03(self):
        """
        鼠标下拉到底部
        :return:
        """
        js = "window.scroll(0,10000000)"
        self.driver.execute_script(js)

    def open_window_handle(self, i):
        """
        浏览器打开多个窗口时，切换到对应的浏览器窗口
        :return:
        """
        handles = self.driver.window_handles  # 获取当前窗口句柄集合（列表类型）
        self.driver.switch_to_window(handles[i])  ##切换到对应的浏览器窗口

    def close_window_handle(self):
        """
        关闭当前浏览器窗口
        :return:
        """
        self.driver.close()

    def to_iframe(self, n):
        """
        跳转到IFRAME
        :return:
        """
        self.driver.switch_to.frame(n)
